<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Function 对象 </title>
    <script>
        /*
          JS 中可以动态的创建函数 它认为函数其实功能完整的对象这一点 和 C++  Java 等有所不同 
          在这些中 函数或者方法 只是对象中的一个方法
        */
        /*
        ECMAScript 最令人感兴趣的可能莫过于函数实际上是功能完整的对象。
        Function 类可以表示开发者定义的任何函数。
        用 Function 类直接创建函数的语法如下：
        var function_name = new function(arg1, arg2, ..., argN, function_body)
        */
        function sayHi(sName,sMessage){
            alert("Hello" + sName + sMessage);
        }

        var sayHi = new Function ("sName","sMessage","alert(\"Hello\" + sName + sMessage);");
        
        function doAdd(iNum) {
            alert(iNum + 20);
        }

        // 这是一种典型的 函数的重载 
        function doAdd(iNum) {
             alert(iNum + 10);
        }

        doAdd(10);	//输出 "20"

        // 和下面这种方式是一样的  
        var doAdd = new Function("iNum", "alert(iNum + 20)");
        var doAdd = new Function("iNum", "alert(iNum + 10)");
        doAdd(10);

        /*
        变量 doAdd 被定义为函数，然后 alsodoAdd 被声明为指向同一个函数的指针。
        用这两个变量都可以执行该函数的代码，并输出相同的结果 - "20"。因此，如果函数名只是指向函数的变量，
        那么可以把函数作为参数传递给另一个函数吗？回答是肯定的！
        */
        function callAnotherFunc(fnFunction,vArgument){
            fnFunction(vArgument);
        }

        var doAdd = new Function("iNum", "alert(iNum + 10)");

        callAnotherFunc(doAdd, 10);	//输出 "20"


        /*
        Function 对象的 length 属性
        如前所述，函数属于引用类型，所以它们也有属性和方法。

        ECMAScript 定义的属性 length 声明了函数期望的参数个数。例如：
        ECMAScript 可以接受任意多个参数（最多 25 个）
        */
        function doAdd(iNum) {
            alert(iNum + 10);
        }

        function sayHi() {
            alert("Hi");
        }

        alert(doAdd.length);	//输出 "1"
        alert(sayHi.length);	//输出 "0"

        /*
        Function 对象的方法
        Function 对象也有与所有对象共享的 valueOf() 方法和 toString() 方法。
        这两个方法返回的都是函数的源代码，在调试时尤其有用。例如：
        */
        function doAdd(iNum) {
        alert(iNum + 10);
        }

        document.write(doAdd.toString());

        // 笔者认为 Js 中的这种方法 给 从Js 中注入代码 到其他的语言中增加了 新的选择这个挺有意思

    </script>
</head>
<body>
    <button onclick="testHowManyArgs()">测试参数的个数</button>
</body>
</html>